<script setup lang="ts">
import { ElInput, ElMessage } from 'element-plus';
import { computed, nextTick, ref } from 'vue';

const props = defineProps<{
    label: string,
    tags: Array<string>,
    alternative?: Array<string>,
}>();

const emit = defineEmits<{ change: [value: Array<string>] }>();

// 响应式标签集
const tags = computed({
    get: () => props.tags,
    set: value => emit('change', value),
});

// input元素
const inputEl = ref<InstanceType<typeof ElInput>>();

// 是否正在输入
const isInputing = ref(false);

// 输入值
const inputValue = ref('');

// 移除标签
const removeTag = (tag: string) => emit('change', tags.value.filter(i => i !== tag));

// 开始输入
const startToInput = () => {
    isInputing.value = true;
    nextTick(() => inputEl.value?.input?.focus());
};

// 完成输入
const endInputing = () => {
    // 验证标签
    if (tags.value.find(i => i === inputValue.value)) ElMessage({ type: 'warning', message: '已添加过相同的标签' });
    else if (inputValue.value) tags.value = [...tags.value, inputValue.value];
    // 重置
    inputValue.value = '';
    isInputing.value = false;
};

// 切换备选使用
const toggleAlternative = (tag: string) => {
    emit('change', tags.value.find(i => i === tag) ? tags.value.filter(i => i !== tag) : [...tags.value, tag]);
};
</script>

<template>
    <el-form-item :label="props.label" label-width="7rem">
        <div class="inline">
            <el-tag v-for="tag in tags" :key="tag" closable @close="removeTag(tag)">{{ tag }}</el-tag>
            <el-input v-if="isInputing" ref="inputEl" v-model="inputValue" @keyup.enter="endInputing"
                @blur="endInputing" />
            <el-button v-else @click="startToInput">+ 新标签</el-button>
        </div>
        <div class="inline" v-if="props.alternative && props.alternative.length > 0">
            <el-tag v-for="tag in alternative" :key="tag" :type="tags.find(i => i === tag) ? 'primary' : 'info'"
                @click="toggleAlternative(tag)">{{ tag }}</el-tag>
        </div>
    </el-form-item>
</template>

<style scoped lang="scss">
.inline {
    display: flex;
    flex-wrap: wrap;
    align-items: center;

    &>span {
        margin: 0.5rem 0.5rem 0 0;
        min-width: 5rem;
        height: 2rem;
    }

    &>div.el-input {
        margin-top: 0.5rem;
        width: 6rem;
    }

    &>button.el-button {
        margin-top: 0.5rem;
    }
}
</style>